import config from '@config/index'
import { BrowserWindow, dialog, shell, screen, app } from 'electron'
import { useProcessException } from '@main/hooks/ExceptionHook'
import icon from '../../../resources/icon.png?asset'
import { WindowConfig } from 'types/global'
import path, { join } from 'path'
import { is } from '@electron-toolkit/utils'
import fs from 'fs'

class MainWindow {
  private loadWindow: BrowserWindow | null
  private mainWindow: BrowserWindow | null
  private userDataPath: string
  private windowStatePath: string
  private childProcessGone: (
    window: BrowserWindow,
    listener?: (
      event: Electron.CrossProcessExports.Event,
      details: Electron.CrossProcessExports.Details
    ) => void
  ) => void

  constructor() {
    const { childProcessGone } = useProcessException()

    this.mainWindow = null
    this.loadWindow = null
    this.childProcessGone = childProcessGone
    this.userDataPath = app.getPath('userData')
    this.windowStatePath = path.join(this.userDataPath, 'windowState.json')
  }

  // 读取窗口配置
  private loadWindowState(): WindowConfig | null {
    try {
      const windowState = JSON.parse(fs.readFileSync(this.windowStatePath, 'utf8'))
      return windowState
    } catch (err) {
      console.error('读取窗口配置失败:', err)
      return null
    }
  }

  // 保存窗口配置
  private saveWindowState(windowState: WindowConfig) {
    try {
      fs.writeFileSync(this.windowStatePath, JSON.stringify(windowState), 'utf8')
    } catch (err) {
      console.error('保存窗口配置失败:', err)
    }
  }

  // 检查窗口位置是否有效
  private isValidPosition(x: number, y: number): boolean {
    const displays = screen.getAllDisplays()
    return displays.some((display) => {
      const { x: displayX, y: displayY, width, height } = display.bounds
      return x >= displayX && x < displayX + width && y >= displayY && y < displayY + height
    })
  }

  // 主窗口函数
  createMainWindow() {
    console.log(path.join(__dirname, '../preload/index.js'))
    // 获取保存的窗口配置
    const savedConfig = this.loadWindowState()

    // 默认窗口配置
    const defaultConfig = {
      width: 1000,
      height: 800,
      minWidth: 1000,
      minHeight: 800,
      x: 0,
      y: 0,
      isMaximized: false
    }

    // 合并配置
    const windowConfig = savedConfig
      ? {
          width: savedConfig.width || defaultConfig.width,
          height: savedConfig.height || defaultConfig.height,
          minWidth: defaultConfig.minWidth,
          minHeight: defaultConfig.minHeight,
          ...(savedConfig.x !== undefined &&
          savedConfig.y !== undefined &&
          this.isValidPosition(savedConfig.x, savedConfig.y)
            ? { x: savedConfig.x, y: savedConfig.y }
            : { x: defaultConfig.x, y: defaultConfig.y })
        }
      : defaultConfig

    this.mainWindow = new BrowserWindow({
      ...windowConfig,
      show: false,
      autoHideMenuBar: false,
      resizable: true,
      frame: false,
      ...(process.platform === 'linux' ? { icon } : {}),
      webPreferences: {
        sandbox: false,
        webSecurity: false,
        // 如果是开发模式可以使用devTools
        devTools: process.env.NODE_ENV === 'development',
        // devTools: true,
        // 在macos中启用橡皮动画
        scrollBounce: process.platform === 'darwin',
        preload: path.join(__dirname, '../preload/index.js'),
        // 启用媒体访问
        nodeIntegration: true,
        contextIsolation: true
      }
    })

    // 加载主窗口
    // HMR for renderer base on electron-vite cli.
    // Load the remote URL for development or the local html file for production.
    if (is.dev) {
      this.mainWindow.loadURL(`http://localhost:${import.meta.env.VITE_PORT}`)
    } else {
      this.mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
    }

    // dom-ready之后显示界面
    this.mainWindow!.once('ready-to-show', () => {
      if (savedConfig && savedConfig.isMaximized) {
        this.mainWindow?.maximize()
      }
      this.mainWindow?.show()
      if (config.UseStartupChart) this.loadWindow?.destroy()
    })

    this.mainWindow.webContents.setWindowOpenHandler((details) => {
      shell.openExternal(details.url)
      return { action: 'deny' }
    })
    // 开发模式下自动开启devtools
    if (process.env.NODE_ENV === 'development') {
      this.mainWindow.webContents.openDevTools({
        mode: 'undocked',
        activate: true
      })
    }

    // 不知道什么原因，反正就是这个窗口里的页面触发了假死时执行
    // 生产模式也打开开发者工具帮助调试
    // this.mainWindow.webContents.openDevTools({
    //   mode: 'undocked',
    //   activate: true
    // })
    this.mainWindow.on('unresponsive', () => {
      dialog
        .showMessageBox(this.mainWindow!, {
          type: 'warning',
          title: '警告',
          buttons: ['重载', '退出'],
          message: '图形化进程失去响应，是否等待其恢复？',
          noLink: true
        })
        .then((res) => {
          if (res.response === 0) this.mainWindow?.reload()
          else this.mainWindow?.close()
        })
    })

    // 窗口最大化
    this.mainWindow.on('maximize', () => {
      this.mainWindow?.webContents.send('window-maximized-change', true)
    })

    // 窗口取消最大化
    this.mainWindow.on('unmaximize', () => {
      this.mainWindow?.webContents.send('window-maximized-change', false)
    })

    // 窗口关闭
    this.mainWindow.on('close', () => {
      if (this.mainWindow) {
        const bounds = this.mainWindow.getBounds()

        this.saveWindowState({
          width: bounds.width,
          height: bounds.height,
          x: bounds.x,
          y: bounds.y,
          isMaximized: this.mainWindow?.isMaximized() || defaultConfig.isMaximized
        })
      }
    })

    /**
     * 新的gpu崩溃检测，详细参数详见：http://www.electronjs.org/docs/api/app
     * @returns {void}
     * @author zmr (umbrella22)
     * @date 2020-11-27
     */
    this.childProcessGone(this.mainWindow)
    this.mainWindow.on('closed', () => {
      this.mainWindow = null
    })
  }
  // 启动加载窗口函数
  loadingWindow(loadingURL: string) {
    this.loadWindow = new BrowserWindow({
      width: 400,
      height: 600,
      frame: false,
      skipTaskbar: true,
      transparent: true,
      resizable: false,
      webPreferences: {
        experimentalFeatures: true,
        preload: join(__dirname, '../preload/index.js')
      }
    })

    this.loadWindow.loadURL(loadingURL)
    this.loadWindow.show()
    this.loadWindow.setAlwaysOnTop(true)
    // 延迟两秒可以根据情况后续调快，= =，就相当于个，sleep吧，就那种。 = =。。。
    setTimeout(() => {
      this.createMainWindow()
    }, 1500)
  }
  // 初始化窗口函数
  initWindow() {
    if (config.UseStartupChart) {
      return this.loadingWindow('')
    } else {
      return this.createMainWindow()
    }
  }
}
export default MainWindow
